Adding Transformation Algorithms
This page page is under construction. |
Introduction
The transform algorithms dictate how each frame is geometrically adjusted using a transformation matrix. Generally, each algorithm can be understood as a method that takes an input frame, an output frame, and a 3x3 transformation matrix, then applies the corresponding warp operation according to the selected backend and runtime settings.
The steps to implement a new transform algorithm are:
- Define the new transform algorithm.
- Define the runtime settings for the algorithm.
Next, we will showcase how to implement any transform algorithm following the previous steps.
Define the Transform Algorithm
The RidgeRun Video Stabilization Library is extensible and can adopt different transform algorithms. Apart from the usual constructor method, the ITransform interface describes how to implement new algorithms with the following methods:
- The Apply method that implements the core transformation algorithm.
- The SetRuntimeSettings method that applies runtime settings to the transform instance.
- The GetRuntimeSettings method that retrieves the current runtime settings.
Additionally, the algorithm can be included in the static builder method of the interface.
Add the Constructor Method
This method should receive a shared pointer to the corresponding runtime settings instance. Since runtime settings are passed through the base interface type, they must be dynamically cast to validate that they match the expected implementation.
ExampleTransform::ExampleTransform(
const std::shared_ptr<IRuntimeSettings> settings) {
auto settings_cast =
std::dynamic_pointer_cast<ExampleRuntimeSettings>(settings);
if (nullptr == settings_cast && nullptr != settings) {
throw RuntimeError{
RuntimeError::IncompatibleParameters,
"The runtime settings are incompatible. Use ExampleRuntimeSettings"};
}
this->settings_ = settings_cast;
}
Extend Static Builder
To enable the ITransform interface to instantiate custom algorithms, it is required to:
- Extend the TransformAlgorithms enumerator class.
- Add the corresponding case to the switch in the builder method.
Extend TransformAlgorithms enum
enum class TransformAlgorithms {
kInvalid = -1,
kTransformOpenCV = 0,
kTransformOpenCL,
kTransformCUDA,
/* add new algorithm */
kExampleTransform,
};
Modify Builder Method
std::shared_ptr<ITransform> ITransform::Build(
const TransformAlgorithms impl,
const std::shared_ptr<IRuntimeSettings> settings) {
switch (impl) {
#ifdef HAVE_OPENCV
case TransformAlgorithms::kTransformOpenCV:
return std::make_shared<TransformOpenCV>(settings);
#endif
#ifdef HAVE_CUDA
case TransformAlgorithms::kTransformCUDA:
return std::make_shared<TransformCUDA>(settings);
#endif
case TransformAlgorithms::kExampleTransform:
return std::make_shared<ExampleTransform>(settings);
default:
throw RuntimeError{RuntimeError::NotImplemented,
"The requested transform implementation is missing or "
"has not been compiled"};
}
return nullptr;
}
Define the Apply Method
The Apply method implements the core transform algorithm. It receives the output frame, the input frame, the transformation matrix, and the transformation configuration parameters. The implementation should apply the desired geometric transformation and write the result to the output frame.
RuntimeError ExampleTransform::Apply(
std::shared_ptr<IImage> outframe,
const std::shared_ptr<IImage> inframe,
const std::array<float, 9> &transformation,
const float crop_margin,
const bool invert,
const bool truncate) {
/* Implement transform algorithm here */
return RuntimeError{};
}
Define the SetRuntimeSettings Method
The SetRuntimeSettings method updates the runtime settings used by the transform instance. Since runtime settings are passed through the base interface type, they must be dynamically cast to validate that they match the expected implementation.
RuntimeError ExampleTransform::SetRuntimeSettings(
const std::shared_ptr<IRuntimeSettings> settings) {
auto settings_cast =
std::dynamic_pointer_cast<ExampleRuntimeSettings>(settings);
if (nullptr == settings_cast && nullptr != settings) {
return RuntimeError{
RuntimeError::IncompatibleParameters,
"The runtime settings are incompatible. Use ExampleRuntimeSettings"};
}
this->settings_ = settings_cast;
return RuntimeError{};
}
Define the GetRuntimeSettings Method
The GetRuntimeSettings method returns a copy of the current runtime settings used by the transform instance.
std::shared_ptr<IRuntimeSettings> ExampleTransform::GetRuntimeSettings() {
auto new_settings = std::make_shared<ExampleRuntimeSettings>();
if (nullptr != this->settings_) {
*new_settings = *this->settings_;
}
return new_settings;
}